Making decisions about whether the performance of an application can be improved, and how to go about doing so, is a task that lies at the crossroads of code optimization and capacity planning. Typically, capacity planning systems attempt to predict performance as a function of demand for a resource versus the available capacity of the resource, e.g., based on various what-if scenarios, capacity planning systems can predict changes to response time, and throughput. Performance tuning needs the same quality of information. Indeed, some performance tuning operations reconfigure resources in exactly the way that a capacity planning exercise would simulate, e.g., adding processors or increasing network capacity.
Capacity planning techniques are quite heavy-weight, involving extensive data collection, modeling and model tuning. For instance, in a typical capacity planning exercise the user tries to fit a curve as precisely as they can. To fit the curve, the user must manually input, into the capacity planning tool, a list of available resources and the way they are interconnected, specify their queuing semantics, measure load characteristics, the set of program tasks (e.g., Servlets), and estimates of response time for each of the program tasks. Then follows a period of manipulating the inputs (often referred to as the parameter tuning or model validation), to ensure a good fit for a predictive formula. This is an extremely laborious task that is generally only performed once.
The goal of this exercise is to come up with a response time of the system for various what-if scenarios, e.g., given the manually input resources and constraints, determine that the response time of the system will be slower than if an additional resource is added. As a result, the user must baby sit the system through a period of curve fitting. In addition, this approach treats the problem as a black box and does not inform the user of how a bottleneck in the system originated.
Likewise, conventional performance tuning tools simply look for hot calling contexts. However, it is difficult to determine if calling one portion of code more than another is actually a problem. This is because performance tuning tools ignore the realities of the systems on which the code executes.
By way of example, if a resource, e.g., a CPU, is saturated and 100 threads are waiting on 4 threads to execute a database access, conventional performance tuning tools would simply attempt to increase a speed of a database access, however, this approach ignores that the CPU is saturated and will just increase pressure on the saturated CPU without improving overall performance.
That is, increasing the performance of a first operation can, and often does, cause a second operation to perform more slowly due to the fact that the second operation now has to share a resource with the first operation. This is often referred to as a zero-sum gain.
Due to the fact that conventional capacity planning and performance tuning tools evaluate changes in system performance from the various what-if scenarios based on a queuing model, they are heavily time dependent and rely on queuing theory. That is, they require simulation of the application on top of the queuing model. Therefore, these tools are not useful for identifying performance problems based on various snapshots of the system at points in time.
As a result, they carry the burden of inspecting the consequences of every change to the system to remain current. Accordingly, they carry a large burden of adapting to changes in the performance landscape of various resources. Axiomatically, conventional capacity planning and performance tuning tools are not useful for providing a lightweight solution for triaging performance problems as they arise throughout the evolution of the system.